package cn.kgm.makeGod;

import cn.kgm.makeGod.condition.WorldState;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Version 1.8
 * @Author: Kappi
 * @Date: 2025-9-11 16:06
 * @Description: cn.kgm.makeGod.RandomCharacterGenerator
 */
public class RandomCharacterGenerator {
    // 姓氏列表
    private static final String[] SURNAMES = {
            "李", "王", "张", "刘", "陈", "杨", "赵", "黄", "周", "吴",
            "徐", "孙", "胡", "朱", "高", "林", "何", "郭", "马", "罗",
            "诸葛", "欧阳", "上官", "司马", "东方", "南宫", "慕容", "公孙", "令狐", "独孤"
    };

    // 男性名字列表
    private static final String[] MALE_NAMES = {
            "伟", "强", "勇", "军", "磊", "洋", "超", "健", "明", "涛",
            "鹏", "华", "平", "鑫", "亮", "刚", "杰", "峰", "建", "波",
            "宇", "浩", "轩", "子墨", "晨风", "天佑", "翰林", "逸尘", "弘文", "博涛"
    };

    // 女性名字列表
    private static final String[] FEMALE_NAMES = {
            "芳", "娜", "敏", "静", "秀英", "丽", "娟", "玲", "霞",
            "燕", "艳", "芳", "颖", "洁", "琳", "婷", "莹", "欣", "怡",
            "雨涵", "梦琪", "忆柳", "之桃", "慕青", "问兰", "元香", "初夏", "沛菡", "傲珊"
    };

    // 外貌特征形容词
    private static final String[] APPEARANCE_ADJECTIVES = {
            "清秀", "俊朗", "妩媚", "英气", "可爱", "成熟", "稚嫩", "沧桑", "威严", "柔和",
            "刚毅", "柔弱", "阳光", "阴郁", "活泼", "文静", "豪放", "内敛", "神秘", "平凡"
    };

    // 眼睛特征
    private static final String[] EYE_FEATURES = {
            "双眸明亮如星", "眼如秋水", "目光锐利", "眼神深邃", "眼睛大而圆", "丹凤眼", "桃花眼",
            "眼神温柔", "目光炯炯", "眼神迷离", "眼带笑意", "目光冷峻", "眼神忧郁"
    };

    // 鼻子特征
    private static final String[] NOSE_FEATURES = {
            "鼻梁高挺", "鼻子小巧", "鼻若悬胆", "鼻翼微张", "鼻尖微翘", "鼻子端正"
    };

    // 嘴唇特征
    private static final String[] MOUTH_FEATURES = {
            "唇红齿白", "薄唇紧抿", "嘴角微扬", "唇形优美", "嘴唇丰满", "嘴角带痣"
    };

    // 发型特征
    private static final String[] HAIR_FEATURES = {
            "乌黑长发", "青丝如瀑", "短发利落", "鬓发如云", "发髻高挽", "青丝束冠",
            "银发如雪", "棕发微卷", "刘海轻拂", "两鬓斑白"
    };

    // 身材特征
    private static final String[] BODY_FEATURES = {
            "身材高挑", "体态娇小", "身形魁梧", "体态轻盈", "身姿曼妙", "体格健壮",
            "瘦削挺拔", "丰腴饱满", "肩宽腰细", "玲珑有致"
    };

    // 气质特征
    private static final String[] TEMPERAMENT_FEATURES = {
            "气质出尘", "英姿飒爽", "温文尔雅", "豪放不羁", "冷若冰霜", "热情如火",
            "沉稳内敛", "活泼灵动", "神秘莫测", "雍容华贵"
    };
    // 性格标签及其权重（权重越高，出现的概率越大）
    private static final Map<PersonalityTag, Integer> PERSONALITY_WEIGHTS = MapUtils.mapOf(
            MapUtils.pair(PersonalityTag.KIND, 30),
            MapUtils.pair(PersonalityTag.EVIL, 15),
            MapUtils.pair(PersonalityTag.LOYAL, 25),
            MapUtils.pair(PersonalityTag.PHILANDERER, 20),
            MapUtils.pair(PersonalityTag.GRUDGE, 10),
            MapUtils.pair(PersonalityTag.ARROGANT, 15),
            MapUtils.pair(PersonalityTag.FAMILY, 20),
            MapUtils.pair(PersonalityTag.AMBITIOUS, 25),
            MapUtils.pair(PersonalityTag.LONER, 10),
            MapUtils.pair(PersonalityTag.SELFISH, 15)
    );
    // 性取向分布
    private static final Map<SexualOrientation, Integer> ORIENTATION_WEIGHTS = MapUtils.mapOf(
            MapUtils.pair(SexualOrientation.HETEROSEXUAL, 70),
            MapUtils.pair(SexualOrientation.HOMOSEXUAL, 10),
            MapUtils.pair(SexualOrientation.BISEXUAL, 20)
    );
    // 随机数生成器
    private static final Random random = new Random();

    public static Location decideNextLocation(Character character, WorldState world) {
        Random random = new Random();
        List<Location> allLocations = new ArrayList<>(world.getLocations().values());

        // 根据性格和需求决定移动倾向
        Map<Location, Integer> locationScores = new HashMap<>();

        for (Location location : allLocations) {
            int score = 0;

            // 1. 资源倾向：前往有可用资源的地方
            for (ResourceNode node : world.getResourceNodes().values()) {
                if (node.getLocation().getId() == location.getId() && node.isAvailable()) {
                    score += 50 + ResourceCompetitionSystem.RESOURCE_VALUES.getOrDefault(node.getItemId(), 0) / 20;
                }
            }

            // 2. 性格倾向
            if (location.getType() == LocationType.TAVERN &&
                    character.hasPersonality(PersonalityTag.PHILANDERER, 50)) {
                score += 40; // 风流的角色喜欢酒馆
            }

            if (location.getType() == LocationType.WILD &&
                    character.hasPersonality(PersonalityTag.LONER, 50)) {
                score += 30; // 孤僻的角色喜欢野外
            }

            if (location.getType() == LocationType.CITY &&
                    character.hasPersonality(PersonalityTag.FAMILY, 50)) {
                score += 35; // 重视家庭的角色喜欢城市
            }

            if (location.getType() == LocationType.DUNGEON &&
                    (character.hasPersonality(PersonalityTag.AMBITIOUS, 50) ||
                            character.hasPersonality(PersonalityTag.EVIL, 40))) {
                score += 45; // 有野心或邪恶的角色喜欢秘境
            }

            // 3. 需求倾向：低生命值倾向于前往安全的地方
            if (character.getCurrentHp() < character.getMaxHp() * 0.4 &&
                    location.getType() == LocationType.CITY) {
                score += 60; // 低生命值时倾向于前往城市
            }

            // 4. 随机因素
            score += random.nextInt(30);

            locationScores.put(location, score);
        }

        // 选择得分最高的地点
        return locationScores.entrySet().stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .orElse(allLocations.get(random.nextInt(allLocations.size())));
    }

    public static Character generateRandomCharacter(int id, List<Character> allCharacters) {
        Character character = generateRandomCharacter(id);

        // 如果已经有其他角色，为当前角色建立初始关系
        if (!allCharacters.isEmpty()) {
            generateInitialRelationships(character, allCharacters);
        }

        // 根据性格设置物品倾向
        generateItemPreferences(character);

        return character;
    }

    /**
     * 根据性格生成物品倾向
     */
    private static void generateItemPreferences(Character character) {
        // 仁善的角色更喜欢疗伤药
        if (character.hasPersonality(PersonalityTag.KIND, 50)) {
            // 可以在这里记录偏好，但在简化版中我们只是设置一个标记
        }

        // 邪恶的角色更喜欢能够提升力量的东西
        if (character.hasPersonality(PersonalityTag.EVIL, 50) ||
                character.hasPersonality(PersonalityTag.AMBITIOUS, 50)) {
            // 偏好提升攻击力的物品
        }

        // 风流的角色更喜欢美酒
        if (character.hasPersonality(PersonalityTag.PHILANDERER, 50)) {
            // 增加前往酒馆的概率
        }

        // 孤僻的角色更喜欢独自采集资源
        if (character.hasPersonality(PersonalityTag.LONER, 50)) {
            // 增加前往野外的概率
        }
    }

    /**
     * 为角色生成初始关系
     *
     * @param character     当前角色
     * @param allCharacters 所有已生成的角色
     */
    private static void generateInitialRelationships(Character character, List<Character> allCharacters) {
        Random random = new Random();

        // 决定建立关系的数量 (1-5个)
        int relationCount = random.nextInt(5) + 1;

        // 随机选择一些角色建立关系
        List<Character> potentialRelations = new ArrayList<>(allCharacters);
        Collections.shuffle(potentialRelations);

        for (int i = 0; i < Math.min(relationCount, potentialRelations.size()); i++) {
            Character other = potentialRelations.get(i);

            // 跳过自己
            if (other.getId() == character.getId()) {
                continue;
            }

            // 根据各种因素决定关系类型和值
            RelationshipType type = determineRelationshipType(character, other);
            int value = determineRelationshipValue(character, other, type);

            // 创建关系
            Relationship relationship = new Relationship(character.getId(), other.getId(), type, value);
            character.addRelationship(relationship);

            // 如果是家庭关系，也需要为对方添加家庭关系
            if (type == RelationshipType.FAMILY) {
                Relationship reverseRelationship = new Relationship(other.getId(), character.getId(), type, value);
                other.addRelationship(reverseRelationship);
            }
        }
    }

    /**
     * 确定关系类型
     */
    private static RelationshipType determineRelationshipType(Character character, Character other) {
        Random random = new Random();

        // 1. 检查是否有家庭关系（同姓概率更高）
        if (character.getName().charAt(0) == other.getName().charAt(0) && random.nextInt(10) < 3) {
            // 随机决定是父母、子女还是兄弟姐妹
            int familyType = random.nextInt(3);
            if (familyType == 0 && character.getAge() > other.getAge() + 20) {
                return RelationshipType.FAMILY; // 可能是父母
            } else if (familyType == 1 && other.getAge() > character.getAge() + 20) {
                return RelationshipType.FAMILY; // 可能是子女
            } else if (Math.abs(character.getAge() - other.getAge()) < 10) {
                return RelationshipType.FAMILY; // 可能是兄弟姐妹
            }
        }

        // 2. 检查性格相容性
        boolean bothKind = character.hasPersonality(PersonalityTag.KIND, 50) &&
                other.hasPersonality(PersonalityTag.KIND, 50);
        boolean bothEvil = character.hasPersonality(PersonalityTag.EVIL, 50) &&
                other.hasPersonality(PersonalityTag.EVIL, 50);
        boolean bothLoyal = character.hasPersonality(PersonalityTag.LOYAL, 50) &&
                other.hasPersonality(PersonalityTag.LOYAL, 50);

        if (bothKind || bothLoyal) {
            return RelationshipType.FRIEND;
        } else if (bothEvil) {
            // 恶人之间也可能是朋友，但也可能是竞争对手
            return random.nextInt(10) < 7 ? RelationshipType.FRIEND : RelationshipType.SWORN_ENEMY;
        }

        // 3. 检查性格冲突
        boolean kindVsEvil = (character.hasPersonality(PersonalityTag.KIND, 50) &&
                other.hasPersonality(PersonalityTag.EVIL, 50)) ||
                (character.hasPersonality(PersonalityTag.EVIL, 50) &&
                        other.hasPersonality(PersonalityTag.KIND, 50));

        if (kindVsEvil) {
            return RelationshipType.SWORN_ENEMY;
        }

        // 4. 默认关系
        int rand = random.nextInt(10);
        if (rand < 4) {
            return RelationshipType.FRIEND;
        } else if (rand < 6) {
            return RelationshipType.STRANGER;
        } else {
            return RelationshipType.SWORN_ENEMY;
        }
    }

    /**
     * 确定关系值
     */
    private static int determineRelationshipValue(Character character, Character other, RelationshipType type) {
        Random random = new Random();
        int baseValue = 0;

        switch (type) {
            case FAMILY:
                baseValue = 60 + random.nextInt(40); // 60-100
                break;
            case FRIEND:
                baseValue = 30 + random.nextInt(50); // 30-80

                // 性格相似的朋友关系更好
                if (hasSimilarPersonalities(character, other)) {
                    baseValue += 20;
                }
                break;
            case STRANGER:
                baseValue = -10 + random.nextInt(20); // -10到10
                break;
            case SWORN_ENEMY:
                baseValue = -80 - random.nextInt(20); // -100到-80
                break;
            case LOVER:
                baseValue = 80 + random.nextInt(20); // 80-100
                break;
            case MASTER_APPRENTICE:
                // 年长的一方是师傅，年轻的一方是学徒
                if (character.getAge() > other.getAge() + 10) {
                    baseValue = 70 + random.nextInt(30); // 70-100
                } else {
                    baseValue = 50 + random.nextInt(30); // 50-80
                }
                break;
        }

        // 确保值在-100到100之间
        return Math.max(-100, Math.min(100, baseValue));
    }

    /**
     * 检查性格相似性
     */
    private static boolean hasSimilarPersonalities(Character c1, Character c2) {
        int similarCount = 0;

        for (PersonalityTag tag : c1.getPersonalities().keySet()) {
            if (c2.hasPersonality(tag, 0)) {
                similarCount++;
            }
        }

        return similarCount >= 2; // 至少有两个相同性格标签
    }

    /**
     * 批量生成随机角色（包含初始关系）
     *
     * @param count 生成数量
     * @return 角色列表
     */
    public static List<Character> generateRandomCharactersWithRelationships(int count) {
        List<Character> characters = new ArrayList<>();

        for (int i = 1; i <= count; i++) {
            Character character = generateRandomCharacter(i, characters);
            characters.add(character);
        }

        return characters;
    }

    /**
     * 生成随机角色
     *
     * @param id 角色ID
     * @return 随机生成的角色
     */
    public static Character generateRandomCharacter(int id) {
        // 随机决定性别
        Gender gender = random.nextBoolean() ? Gender.MALE : Gender.FEMALE;

        // 生成随机名字
        String name = generateRandomName(gender);

        // 生成随机年龄 (12-100岁)
        int age = random.nextInt(18) + 7;

        // 生成随机等级 (1-30级)
        int level = random.nextInt(30) + 1;

        // 生成随机属性
        int charm = random.nextInt(101) + 1; // 魅力 0-100
        int luck = random.nextInt(101) + 1;  // 运气 0-100
        int attack = level * 2 + random.nextInt(10); // 攻击力
        int defense = level * 1 + random.nextInt(10); // 防御力
        int maxHp = level * 10 + random.nextInt(50); // 最大生命值

        // 创建角色
        Character character = new Character(id, name, level, charm, luck);
        character.setAttack(attack);
        character.setDefense(defense);
        character.setMaxHp(maxHp);
        character.setCurrentHp(maxHp);
        character.setAge(age);
        character.setGender(gender);

        // 生成外貌描写
        String appearance = generateAppearanceDescription(gender);
        character.setAppearanceDescription(appearance);

        // 生成性格标签
        generateRandomPersonalities(character);

        // 生成性取向
        SexualOrientation orientation = generateRandomOrientation();
        character.setSexualOrientation(orientation);

        // 初始位置设置为空，由调用者设置
        return character;
    }

    /**
     * 生成随机名字
     *
     * @param gender 性别
     * @return 随机名字
     */
    private static String generateRandomName(Gender gender) {
        String surname = SURNAMES[random.nextInt(SURNAMES.length)];
        String givenName;

        if (gender == Gender.MALE) {
            givenName = MALE_NAMES[random.nextInt(MALE_NAMES.length)];
        } else {
            givenName = FEMALE_NAMES[random.nextInt(FEMALE_NAMES.length)];
        }

        // 10%的概率使用双字名
        if (random.nextInt(10) == 0) {
            String secondName;
            if (gender == Gender.MALE) {
                secondName = MALE_NAMES[random.nextInt(MALE_NAMES.length)];
            } else {
                secondName = FEMALE_NAMES[random.nextInt(FEMALE_NAMES.length)];
            }
            givenName += secondName;
        }

        return surname + givenName;
    }

    /**
     * 生成外貌描写
     *
     * @param gender 性别
     * @return 外貌描写字符串
     */
    private static String generateAppearanceDescription(Gender gender) {
        List<String> features = new ArrayList<>();

        // 添加外貌形容词
        features.add(APPEARANCE_ADJECTIVES[random.nextInt(APPEARANCE_ADJECTIVES.length)]);

        // 添加眼睛特征
        if (random.nextInt(10) < 8) { // 80%概率有眼睛特征
            features.add(EYE_FEATURES[random.nextInt(EYE_FEATURES.length)]);
        }

        // 添加鼻子特征
        if (random.nextInt(10) < 5) { // 50%概率有鼻子特征
            features.add(NOSE_FEATURES[random.nextInt(NOSE_FEATURES.length)]);
        }

        // 添加嘴唇特征
        if (random.nextInt(10) < 5) { // 50%概率有嘴唇特征
            features.add(MOUTH_FEATURES[random.nextInt(MOUTH_FEATURES.length)]);
        }

        // 添加发型特征
        if (random.nextInt(10) < 7) { // 70%概率有发型特征
            features.add(HAIR_FEATURES[random.nextInt(HAIR_FEATURES.length)]);
        }

        // 添加身材特征
        if (random.nextInt(10) < 6) { // 60%概率有身材特征
            features.add(BODY_FEATURES[random.nextInt(BODY_FEATURES.length)]);
        }

        // 添加气质特征
        if (random.nextInt(10) < 4) { // 40%概率有气质特征
            features.add(TEMPERAMENT_FEATURES[random.nextInt(TEMPERAMENT_FEATURES.length)]);
        }

        // 组合所有特征
        return String.join("，", features) + "。";
    }

    /**
     * 为角色生成随机性格标签
     *
     * @param character 角色
     */
    private static void generateRandomPersonalities(Character character) {
        // 决定性格标签数量 (1-3个)
        int count = random.nextInt(3) + 1;

        // 转换为列表以便随机选择
        List<PersonalityTag> allTags = new ArrayList<>(PERSONALITY_WEIGHTS.keySet());
        List<Integer> weights = new ArrayList<>(PERSONALITY_WEIGHTS.values());

        // 已选择的标签，避免重复
        Set<PersonalityTag> selectedTags = new HashSet<>();

        for (int i = 0; i < count; i++) {
            // 加权随机选择
            PersonalityTag selectedTag = weightedRandomSelection(allTags, weights);

            // 如果已经选择了这个标签，尝试选择另一个
            if (selectedTags.contains(selectedTag)) {
                // 创建一个不包括已选标签的列表
                List<PersonalityTag> availableTags = allTags.stream()
                        .filter(tag -> !selectedTags.contains(tag))
                        .collect(Collectors.toList());

                List<Integer> availableWeights = availableTags.stream()
                        .map(PERSONALITY_WEIGHTS::get)
                        .collect(Collectors.toList());

                if (!availableTags.isEmpty()) {
                    selectedTag = weightedRandomSelection(availableTags, availableWeights);
                }
            }

            // 设置强度 (50-100)
            int intensity = random.nextInt(51) + 50;
            character.addPersonality(selectedTag, intensity);
            selectedTags.add(selectedTag);
        }
    }

    /**
     * 加权随机选择
     *
     * @param items   选项列表
     * @param weights 权重列表
     * @return 随机选择的项目
     */
    private static <T> T weightedRandomSelection(List<T> items, List<Integer> weights) {
        int totalWeight = weights.stream().mapToInt(Integer::intValue).sum();
        int randomValue = random.nextInt(totalWeight);

        int cumulativeWeight = 0;
        for (int i = 0; i < items.size(); i++) {
            cumulativeWeight += weights.get(i);
            if (randomValue < cumulativeWeight) {
                return items.get(i);
            }
        }

        return items.get(items.size() - 1); // 应该不会执行到这里
    }

    /**
     * 生成随机性取向
     *
     * @return 性取向
     */
    private static SexualOrientation generateRandomOrientation() {
        List<SexualOrientation> orientations = new ArrayList<>(ORIENTATION_WEIGHTS.keySet());
        List<Integer> weights = new ArrayList<>(ORIENTATION_WEIGHTS.values());
        return weightedRandomSelection(orientations, weights);
    }

    /**
     * 批量生成随机角色
     *
     * @param count 生成数量
     * @return 角色列表
     */
    public static List<Character> generateRandomCharacters(int count) {
        List<Character> characters = new ArrayList<>();
        for (int i = 1; i <= count; i++) {
            characters.add(generateRandomCharacter(i));
        }
        return characters;
    }

    public enum Gender {
        MALE("男"), FEMALE("女");

        private final String displayName;

        Gender(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return displayName;
        }
    }

    public enum SexualOrientation {
        HETEROSEXUAL("异性恋"),
        HOMOSEXUAL("同性恋"),
        BISEXUAL("双性恋");

        private final String displayName;

        SexualOrientation(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return displayName;
        }
    }
}
